__author__ = 'wangjc'

import pytest
from Common.BaseDriver import BaseDriver
import subprocess
from DataBase.RedisOperate import RedisOperate
from contants.Param import Param
from Common.BaseUtil import BaseUtil
from DataBase.Sql import QuerySql
import os
from Common.conf_dir import htmlreports_dir
import sys
import contants.globalvar as gl
import allure

params=["Honor_V8"] #控制用例执行几遍


@pytest.fixture(params=params,scope='module')
def login_common_driver(packageEnv,end,env,email,curTime):
    # 获取驱动后开始执行用例
    dbConnect = gl.get_value('dbConnect')
    driver = ''
    print(params)
    try:
        envInfo = QuerySql.queryEnv('',env,dbConnect)
        trans = BaseUtil.excuteSsh('',envInfo)
        driver = BaseDriver().base_driver(dbConnect,packageEnv,end,env,trans)
        gl.set_value('driver', driver)
        package = QuerySql.queryPackage('',end,dbConnect)
    except:
        close(dbConnect,driver,end,trans,package,email,curTime)

    # 用yield唤醒tear down
    yield driver
    close(dbConnect, driver, end,trans,package,email,curTime)

#提取共通方法
def close(dbConnect,driver,end,trans,package,email,curTime):
    # 判断driver是否为字符串类型，字符串类型代表执行用例前环境异常，可通过报告查看异常原因
    if isinstance(driver,str) == False:
        # 关闭数据库连接
        dbConnect.close
        port = RedisOperate().getHashToRedis(Param.appiumHashKey, end).decode('utf-8')
        closeAppium(BaseDriver().shellFlg, port,package)
        # 从redis中删除关闭的端口
        RedisOperate().delPortToRedis(port, Param.appiumListKey)
        RedisOperate().delHashToRedis(Param.appiumHashKey, end, port)
        trans.close()
        # 所有用例执行后关闭app
        driver.quit()
        # driver.close_app()
        # res = startAllure(curTime)
        # reciver = [email]
        # msg = res
        # MailUtil.sendMail(reciver,msg)
    else:
        assert driver

# 定义自定义参数，pytest.main执行时作为参数传入（优先于test用例执行）
def pytest_addoption(parser):
    parser.addoption(
        "--packageEnv",
        action="store",
        default='127',
        help="assign which packageEnv to use",
    ),
    parser.addoption(
        "--end",
        action="store",
        default='driver',
        help="assign which end to use",
    ),
    parser.addoption(
        "--env",
        action="store",
        default='local',
        help="assign which env to use",
    ),
    parser.addoption(
        "--email",
        action="store",
        default='local',
        help="assign which email to use",
    ),
    parser.addoption(
        "--curTime",
        action="store",
        default='local',
        help="assign which curTime to use",
    ),
    parser.addoption(
        "--storyId",
        action="store",
        default='local',
        help="assign which storyId to use",
    ),
    parser.addoption(
        "--autoType",
        action="store",
        default='local',
        help="assign which autoType to use",
    ),
    parser.addoption(
        "--ver",
        action="store",
        default='local',
        help="assign which --ver to use",
    ),
    parser.addoption(
        "--assignId",
        action="store",
        default='local',
        help="assign which --assignId to use",
    )

#获取注册的参数并设置到当前系统中，可在其他文件直接调用
def pytest_configure(config):
    os.environ["storyId"] = config.getoption('storyId')
    os.environ["packageEnv"] = config.getoption('packageEnv')
    os.environ["end"] = config.getoption('end')
    os.environ["env"] = config.getoption('env')

# 和addoption配合使用
# app包
@pytest.fixture(scope="session", autouse=True)
def packageEnv(request):
    return request.config.getoption("--packageEnv")
# 测试的端
@pytest.fixture(scope="session", autouse=True)
def end(request):
    return request.config.getoption("--end")
# 设备环境
@pytest.fixture(scope="session", autouse=True)
def env(request):
    return request.config.getoption("--env")

@pytest.fixture(scope="session", autouse=True)
def email(request):
    return request.config.getoption("--email")

@pytest.fixture(scope="session", autouse=True)
def curTime(request):
    return request.config.getoption("--curTime")
# 功能id
@pytest.fixture(scope="session", autouse=True)
def storyId(request):
    storyid = request.config.getoption("--storyId")
    gl.set_value('storyId', storyid)
    return storyid
# 自动化类型
@pytest.fixture(scope="session", autouse=True)
def autoType(request):
    return request.config.getoption("--autoType")
# 版本号
@pytest.fixture(scope="session", autouse=True)
def ver(request):
    return request.config.getoption("--ver")
# 数据套（指定哪套数据测试）
@pytest.fixture(scope="session", autouse=True)
def assignId(request):
    return request.config.getoption("--assignId")

def closeAppium(shellFlg, portParam,package):
    if portParam != '':
        closeShell = "netstat -nlp | grep " + portParam + " | awk '{print $7}'"
        try:
            pid = subprocess.check_output(closeShell, shell=shellFlg)
            temp = pid.decode('utf-8').replace('\n','')
            subprocess.check_output('kill  -9  ' + str(temp), shell=shellFlg)
            print(package[0][0])
            # 杀掉app进程
            subprocess.check_output('adb shell am force-stop ' + str(package[0][0]), shell=shellFlg)
        except:
            return

#每个测试步骤后判断是否成功，失败情况截图
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
    '''
    获取每个用例状态的钩子函数
    :param item:
    :param call:
    :return:
    '''
    driverTemp = gl.get_value('driver')
    # 获取钩子方法的调用结果
    outcome = yield
    rep = outcome.get_result()
    # 仅仅获取用例call 执行结果是失败的情况, 不包含 setup/teardown
    if rep.when == "call" and rep.failed:
        mode = "a" if os.path.exists("failures") else "w"
        with open("failures", mode) as f:
            # let's also access a fixture for the fun of it
            if "tmpdir" in item.fixturenames:
                extra = " (%s)" % item.funcargs["tmpdir"]
            else:
                extra = ""
            f.write(rep.nodeid + extra + "\n")
        # 添加allure报告截图
        if hasattr(driverTemp, "get_screenshot_as_png"):
            with allure.step('添加失败截图...'):
                allure.attach(driverTemp.get_screenshot_as_png(), "失败截图", allure.attachment_type.PNG)


# 本地启动allure服务并发送邮件
def startAllure(curTime):
    curPath = os.path.abspath(os.path.dirname(__file__))
    rootPath = os.path.split(curPath)[0]
    sys.path.append(os.path.split(rootPath)[0])
    cmd = 'allure serve '+htmlreports_dir + "\\APP_AutoTest_Reports_{0}.xml".format(curTime)
    res = os.popen(cmd)
    print(res.read())
    return res.read()

